/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.blue.module;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

/**
 *
 * @author kelvio.matias
 */
public class ModuleManager {

    private Map<String, Map<String, ModuleInfo>> moduleInfoMap = new HashMap<>();
    private Map<String, Map<String, Boolean>> loadedModuleMap = new HashMap<>();
    private ModuleLoader moduleLoader;

    private ModuleManager() {
        moduleLoader = new DefaultModuleLoader();
    }

    public static ModuleManager getInstance() {
        return ModuleManager.ModuleManagerHolder.INSTANCE;
    }

    private static class ModuleManagerHolder {

        private static final ModuleManager INSTANCE = new ModuleManager();
    }

    public final void register(ModuleInfo... list) {
        for (ModuleInfo info : list) {
            this.register(info);
        }
    }

    public final void register(ModuleInfo info) {
        if (info == null) {
            throw new IllegalArgumentException("The module info cannot be null.");
        }
        if (!this.moduleInfoMap.containsKey(info.getName())) {
            this.moduleInfoMap.put(info.getName(), new HashMap<String, ModuleInfo>());
        }
        this.moduleInfoMap.get(info.getName()).put(info.getVersion(), info);
    }

    public ModuleInfo getModuleInfo(String name, String version) {
        if (!this.moduleInfoMap.containsKey(name)) {
            return null;
        }
        return this.moduleInfoMap.get(name).get(version);
    }
    
    public boolean containsModuleInfo(String name, String version) {
        if (!this.moduleInfoMap.containsKey(name)) {
            return false;
        }
        if (!this.moduleInfoMap.get(name).containsKey(version)) {
            return false;
        }
        return true;
    }
    
    /**
     *
     * @param name
     * @param version
     */
    public void loadModule(String name, String version) {
        if (!this.moduleInfoMap.containsKey(name)) {
            throw new ModuleNotFoundException("The module " + name + " cannot be found.");
        }
        if (!this.moduleInfoMap.get(name).containsKey(version)) {
            throw new ModuleNotFoundException("The module " + name + " " + version + " cannot be found.");
        }
        if (this.loadedModuleMap.containsKey(name) && this.loadedModuleMap.get(name).containsKey(version)) {
            return;
        }
        this.moduleLoader.load(this.moduleInfoMap.get(name).get(version));
    }
    
    public void addPath(File path) {
        throw new UnsupportedOperationException("Not implemented yet");
    }
}
